home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / ENV Server / library src / GetPutEnv.c next >
Encoding:
C/C++ Source or Header  |  1993-05-31  |  6.8 KB  |  293 lines  |  [TEXT/ALFA]

  1. /*
  2. ** GetPutEnv.h
  3. **
  4. ** Contains the source for the Getenv() and Putenv() calls.
  5. ** Implements the server-based environment variables on the Macintosh.
  6. **
  7. ** The code is freely distributable and modifiable, but you must keep
  8. ** the following information in the code and any derived works.
  9. **
  10. ** Copyright (C) 1993 by Brent Burton
  11. ** Brent Burton
  12. ** brentb@tamsun.tamu.edu
  13. **
  14. ** 5/12/93 - created
  15. ** 5/31/93 - slightly modified for distributing.
  16. */
  17.  
  18. #include "es_headers"
  19. #include <Traps.h>
  20. #include <Errors.h>        /* Macintosh error codes */
  21. #include <BDC.h>
  22. #include <pascal.h>        /* for pascal-C string conversions */
  23. #include "GetPutEnv.h"
  24. #include "GetPutEnvP.h"
  25. #include "utils.h"
  26.  
  27.  
  28. static Boolean FindAProcess( OSType sig, ProcessSerialNumber *process);
  29. static Boolean Check4Traps(void);
  30. static OSErr ESFindServer(AEAddressDesc *target);
  31. static OSErr ESGetReply( AppleEvent *theReply, Ptr *result);
  32. static OSErr ESPutReply( AppleEvent *theReply, int *result);
  33.  
  34.  
  35. /***********************************************************
  36. ** Getenv
  37. **
  38. ** Looks up the value of varname's string and returns:
  39. **  NULL:  if name doesn't exist or an error occurred.
  40. **  Ptr: if name existed and its value could be fetched.
  41. **
  42. ** Note that normal getenv() returns a pointer to a static
  43. ** area.  THIS Getenv() returns a pointer created by NewPtr.
  44. ** The caller will need to DisposPtr for cleanliness, but most likely,
  45. ** the pointer will not be large and can be ignored...(not suggested).
  46. *****************/
  47.  
  48. char *Getenv (const char *varname)
  49. {
  50.     OSErr err, sendErr;
  51.     AppleEvent theAE, theReply;
  52.     AEAddressDesc target;
  53.     short msgLen;
  54.     Ptr result = NULL;
  55.  
  56.     if (!Check4Traps())
  57.         return NULL;
  58.     
  59.     msgLen = (short)mystrlen( (Ptr)varname);
  60.     err = ESFindServer( &target);
  61.     
  62.     if (err == noErr)
  63.     {
  64.         err = AECreateAppleEvent( kESEventClass, kESGetEnvMsg, &target,
  65.                 kAutoGenerateReturnID, kAnyTransactionID, &theAE);
  66.         
  67.         if ( err == noErr)
  68.         {
  69.             /* now the apple event has been created, add the length
  70.             ** of the string, and the string as two parameters.
  71.             */
  72.             err = AEPutKeyPtr( &theAE, keyESLen, typeShortInteger, (Ptr)&msgLen,
  73.                     sizeof(short));
  74.             
  75.             if (err == noErr)
  76.             {
  77.                 /* Just send string's bytes, no nul end nor length prefix */
  78.                 err = AEPutKeyPtr(&theAE, keyESString, typeChar, (Ptr)varname,
  79.                         (Size)msgLen);
  80.                 /*
  81.                 ** Now send the request to the server & expect a
  82.                 ** reply.
  83.                 */
  84.                 if (err == noErr)
  85.                     sendErr = AESend( &theAE, &theReply, kAEWaitReply,
  86.                                 kAENormalPriority, 600L /* 10 secs */,
  87.                                 NULL, NULL);
  88.                 
  89.                 if (sendErr == noErr)
  90.                 {
  91.                     /* We sent and received a decent message.  Now extract
  92.                     ** the string returned from the server if successful.
  93.                     */
  94.                     err = ESGetReply( &theReply, &result);
  95.                 }
  96.             }
  97.             err = AEDisposeDesc( &theAE);
  98.         }
  99.         err = AEDisposeDesc( &target);
  100.     }
  101.  
  102.     return result;
  103. } /* Getenv */
  104.  
  105.  
  106. /***********************************************************/
  107.  
  108. int Putenv (const char *s)
  109. {
  110.     OSErr err, sendErr;
  111.     AppleEvent theAE, theReply;
  112.     AEAddressDesc target;
  113.     short msgLen;
  114.     int result = 1;        /* assume failure */
  115.  
  116.     if (!Check4Traps())
  117.         return 1;
  118.  
  119.     msgLen = (short)mystrlen( (Ptr)s);
  120.     err = ESFindServer( &target);
  121.     
  122.     if (err == noErr)
  123.     {
  124.         err = AECreateAppleEvent( kESEventClass, kESPutEnvMsg, &target,
  125.                 kAutoGenerateReturnID, 0L, &theAE);
  126.         
  127.         if ( err == noErr)
  128.         {
  129.             /* now the apple event has been created, add the length
  130.             ** of the string, and the string as two parameters.
  131.             */
  132.             err = AEPutKeyPtr( &theAE, keyESLen, typeShortInteger, (Ptr)&msgLen,
  133.                     sizeof(short));
  134.             
  135.             if (err == noErr)
  136.             {
  137.                 /* Just send string's bytes, no nul end nor length prefix */
  138.                 err = AEPutKeyPtr(&theAE, keyESString, typeChar, (Ptr)s,
  139.                         (Size)msgLen);
  140.                 /*
  141.                 ** Now send the request to the server & expect a
  142.                 ** reply.
  143.                 */
  144.                 if (err == noErr)
  145.                     sendErr = AESend( &theAE, &theReply, kAEWaitReply,
  146.                                 kAENormalPriority, 600L /* 10 secs */,
  147.                                 NULL, NULL);
  148.                 
  149.                 if (sendErr == noErr)
  150.                 {
  151.                     /* We sent and received a decent message.  Now extract
  152.                     ** the string returned from the server if successful.
  153.                     */
  154.                     err = ESPutReply( &theReply, &result);
  155.                 }
  156.             }
  157.             err = AEDisposeDesc( &theAE);
  158.         }
  159.         err = AEDisposeDesc( &target);
  160.     }
  161.  
  162.     return result;
  163. } /* Putenv */
  164.  
  165.  
  166. /***********************************************************/
  167.  
  168. static OSErr ESGetReply( AppleEvent *theReply, Ptr *result)
  169. {
  170.     short msgLen;
  171.     Ptr msgBuf=NULL;
  172.     OSErr err;
  173.     DescType foo;
  174.     Size actualSize;
  175.     Boolean flag;
  176.     
  177.     *result = NULL;
  178.     
  179.     err = AEGetKeyPtr( theReply, keyESFlag, typeBoolean, &foo, (Ptr)&flag,
  180.             sizeof(Boolean), &actualSize);
  181.  
  182.     if (err == noErr && flag)
  183.     {
  184.         err = AEGetKeyPtr( theReply, keyESLen, typeShortInteger, &foo,
  185.                 (Ptr)&msgLen, sizeof(short), &actualSize);
  186.                 
  187.         if (err == noErr)  /* then we have the string length */
  188.         {
  189.             msgBuf = NewPtrClear( msgLen + 1);  /* make +1 for nul end */
  190.             if (msgBuf != NULL)
  191.             {
  192.                 err = AEGetKeyPtr( theReply, keyESString, typeChar, &foo, msgBuf,
  193.                         msgLen, &actualSize);
  194.  
  195.                 if (err == noErr)
  196.                 {
  197.                     *result = msgBuf;
  198.                 }
  199.             }
  200.             else
  201.                 return memFullErr;
  202.         }
  203.     }
  204.     return err;
  205. } /* ESGetReply */
  206.  
  207.  
  208. /***********************************************************/
  209.  
  210. static OSErr ESPutReply( AppleEvent *theReply, int *result)
  211. {
  212.     short msgLen;
  213.     Ptr msgBuf=NULL;
  214.     OSErr err;
  215.     DescType foo;
  216.     Size actualSize;
  217.     Boolean flag;
  218.     
  219.     err = AEGetKeyPtr( theReply, keyESFlag, typeBoolean, &foo, (Ptr)&flag,
  220.             sizeof(Boolean), &actualSize);
  221.  
  222.      /* Putenv()'s success(0) if no error & flag is true */
  223.     *result = !(err == noErr && flag);
  224.     
  225.     return err;
  226. } /* ESPuttReply */
  227.  
  228.  
  229. /***********************************************************/
  230.  
  231. static Boolean FindAProcess( OSType sig, ProcessSerialNumber *process)
  232. {
  233.     Boolean found = FALSE;
  234.     ProcessInfoRec info;
  235.  
  236.     process->highLongOfPSN = 0L;
  237.     process->lowLongOfPSN = kNoProcess;
  238.     info.processInfoLength = sizeof(ProcessInfoRec);
  239.     info.processName = NULL;
  240.     info.processAppSpec = NULL;
  241.     
  242.     while (GetNextProcess(process) == noErr)
  243.     {
  244.         if (GetProcessInformation(process, &info) == noErr)
  245.         {
  246.             if ( (info.processType == (long)'APPL') &&
  247.                  (info.processSignature == sig))
  248.             {
  249.                 found = TRUE;  /* we found it! */
  250.                 break;
  251.             }
  252.         }
  253.     }
  254.     return found;
  255. } /* FindAProcess */
  256.  
  257.  
  258. /***********************************************************/
  259.  
  260. static OSErr ESFindServer(AEAddressDesc *target)
  261. {
  262.     OSErr err = noErr;
  263.     ProcessSerialNumber PSN;
  264.     
  265.     if ( FindAProcess( kESSignature, &PSN))
  266.     {
  267.         err = AECreateDesc( typeProcessSerialNumber, (Ptr)&PSN,
  268.                     sizeof(PSN), target);
  269.         return err;
  270.     }
  271.     else
  272.         return !noErr;  /* return something other than noErr */
  273. } /* ESFindServer */
  274.  
  275.  
  276. /***********************************************************/
  277.  
  278.  
  279. static Boolean Check4Traps(void)
  280. {
  281.     Boolean result;
  282.     long    r;
  283.     
  284.     result = (TrapAvailable(_WaitNextEvent) &&
  285.                 TrapAvailable(_GestaltDispatch) &&
  286.                 (Gestalt(gestaltAppleEventsAttr, &r) == noErr) &&
  287.                 ((r & (1 << gestaltAppleEventsPresent)) != 0));
  288.     
  289.     return (result);
  290. }
  291.  
  292.  
  293.